package com.mikelouis.test.scala.impatient.chapter22_continuations

/**
 * Created by yuazhu on 5/22/2015.
 */
object Chapter22 extends App {
  // 1
  {
    //    import util.continuations._
    //
    //    var cont: (String => Unit) = null
    //    var filename = "/tmp/myfile.txt"
    //    var contents = ""
    //
    //    reset {
    //      while (contents == "") {
    //        try {
    //          contents = io.Source.fromFile(filename, "UTF-8").mkString
    //        } catch {
    //          case _: Throwable =>
    //        }
    //
    //        filename = shift { k: (String => Unit) =>
    //          cont = k
    //        }
    //      }
    //    }
    //
    //    if (contents == "") {
    //      print("Try another file: ")
    //      val fn = readLine()
    //      cont(fn)
    //    }
    //    println(contents)
  }

  // 3
  {
    import util.continuations._
    import java.io.File
    class FileIterator(startDir: File) extends Iterator[File] {
      var cont: Unit => Unit = null
      private var _hasNext = true
      private var _finished = false
      private var _crtFile: File = null

      reset {
        processDirectory(startDir)
      }

      def processDirectory(dir: File): Unit@cps[Unit] = {
        val files = dir.listFiles

        var i = 0
        while (i < files.length) {
          val f = files(i)
          i += 1

          if (f.isDirectory) {
            processDirectory(f)
          } else {
            shift {
              k: (Unit => Unit) => {
                cont = k
              }
            }

            _crtFile = f
          }
        }
        _finished = true
      }

      def hasNext = _hasNext

      def next() = {
        cont()
        if (_hasNext) {
          if (_finished)
            _hasNext = false
          _crtFile
        } else
          throw new java.util.NoSuchElementException("next on empty iterator")
      }
    }

    val fit = new FileIterator(new File(args(0)))
    for (i <- 1 to args(1).toInt) {
      if (fit.hasNext)
        println(fit.next())
    }
  }

  // 4
  {
//    import java.awt._
//    import java.awt.event._
//    import javax.swing._
//    import scala.util.continuations._
//
//    var cont: Unit => Unit = null
//
//    val frame = new JFrame
//    val button = new JButton("Next")
//    setListener(button) {
//      reset {
//        run()
//      }
//    }
//    val textField = new JTextArea(10, 40)
//    textField.setEnabled(true)
//    val label = new JLabel("Welcome to the demo app")
//    frame.add(label, BorderLayout.NORTH)
//    frame.add(textField)
//    val panel = new JPanel
//    panel.add(button)
//    frame.add(panel, BorderLayout.SOUTH)
//    frame.pack()
//    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
//    frame.setVisible(true)
//
//    def run(): Unit@cps[Unit] = {
//      val response1 = getResponse("What is your first name?")
//      val response2 = getResponse("What is your last name?")
//      process(response1, response2)
//    }
//
//    def process(s1: String, s2: String) {
//      label.setText("Hello, " + s1 + " " + s2)
//    }
//
//    def getResponse(prompt: String): String@cps[Unit] = {
//      label.setText(prompt)
//      setListener(button) {
//        cont()
//      }
//      shift {
//        k: (Unit => Unit) => {
//          cont = k
//        }
//      }
//      setListener(button) {}
//      textField.getText
//    }
//
//    def setListener(button: JButton)(action: => Unit) {
//      for (l <- button.getActionListeners) button.removeActionListener(l)
//      button.addActionListener(new ActionListener {
//        override def actionPerformed(event: ActionEvent) {
//          action
//        }
//      })
//    }
  }
}
